package com.zufangbao.earth.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.transaction.Transactional;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.demo2do.core.persistence.support.Filter;
import com.demo2do.core.service.impl.GenericServiceImpl;
import com.zufangbao.earth.entity.particalsystem.AppParticles;
import com.zufangbao.earth.entity.particalsystem.Partical;
import com.zufangbao.earth.entity.particalsystem.ParticalModel;
import com.zufangbao.earth.service.AppParticlesService;
import com.zufangbao.earth.service.ParticalModelService;
import com.zufangbao.earth.service.ParticalService;
import com.zufangbao.gluon.api.quark.ParticalStatus;
import com.zufangbao.gluon.api.quark.ParticalType;
import com.zufangbao.gluon.exception.CommonException;
import com.zufangbao.gluon.opensdk.Md5Util;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth;
import com.zufangbao.gluon.spec.earth.GlobalSpec4Earth.ErrorCode4ParticalSystem;

@Service("particalService")
@Transactional
public class ParticalServiceImpl extends GenericServiceImpl<Partical> implements ParticalService {
	
	@Autowired
	private ParticalModelService  particalModelService;
	
	@Autowired
	private AppParticlesService appParticlesService;
	
	@Override
	public void createPartical(Partical partical) throws CommonException {
		
		if(null == partical){
			
			throw new CommonException(ErrorCode4ParticalSystem.ERROR_TRY_TO_CREATE_PARTICALS_WITH_INVALID_DATA);
		}
		if(StringUtils.isEmpty(partical.getUniqueParticalId())){
			
			throw new CommonException(ErrorCode4ParticalSystem.ERROR_TRY_TO_CREATE_PARTICALS_WITH_INVALID_DATA);
			
		}
		String querySentence = "FROM Partical partical WHERE partical.uniqueParticalId = :uniqueParticalId";
		
		@SuppressWarnings("unchecked")
		List<Partical> paritcalList = genericDaoSupport.searchForList(querySentence, "uniqueParticalId", partical.getUniqueParticalId());
		
		if(CollectionUtils.isNotEmpty(paritcalList)){
			
			throw new CommonException(ErrorCode4ParticalSystem.ERROR_TRY_TO_CREATE_DUPLICATE_PARTICALS);
			
		}
		genericDaoSupport.save(partical);
		
	}

	@Override
	public Partical getParticalByName(String name) {
		
		if(StringUtils.isEmpty(name)){
			
			return null;
		}
		
		String querySentence = "FROM Partical partical WHERE partical.particalName = :particalName";
		
		@SuppressWarnings("unchecked")
		List<Partical> paritcalList = genericDaoSupport.searchForList(querySentence, "particalName", name);
		
		if(CollectionUtils.isEmpty(paritcalList)){
			
			return null;
		}
		return paritcalList.get(0);
	}

	@Override
	public void deleteParticalByUniqueId(String uniqueId) {
		
		if(StringUtils.isEmpty(uniqueId)){
			
			return;
		}
		
		String querySentence = "FROM Partical partical WHERE partical.uniqueParticalId = :uniqueParticalId";
		
		@SuppressWarnings("unchecked")
		List<Partical> paritcalList = genericDaoSupport.searchForList(querySentence, "uniqueParticalId", uniqueId);
		
		if(CollectionUtils.isEmpty(paritcalList)){
			
			return;
		}
		Partical partical = paritcalList.get(0);
		
		genericDaoSupport.delete(partical);
		
	}

	@Override
	public Partical getParticalByUniqueId(String uniqueId) {
		
		if(StringUtils.isEmpty(uniqueId)){
			
			return null;
		}
		
		String querySentence = "FROM Partical partical WHERE partical.uniqueParticalId = :uniqueParticalId";
		
		@SuppressWarnings("unchecked")
		List<Partical> paritcalList = genericDaoSupport.searchForList(querySentence, "uniqueParticalId", uniqueId);
		
		if(CollectionUtils.isEmpty(paritcalList)){
			
			return null;
		}
		
		return paritcalList.get(0);
	}

	@Override
	public String updateSinglePartical(Partical partical, String originalUniqueId) {
		
		
		String entryUrl = partical.getEntryUrl();
		
		String newUniqueId = Md5Util.encode(entryUrl);
		
		partical.setUniqueParticalId(newUniqueId);
		
		genericDaoSupport.saveOrUpdate(partical);
		
		return newUniqueId;
		
	}

	@Override
	public void deleteParticalAndModelsByUniqueId(String particalUniqueId) {
		
		deleteParticalByUniqueId(particalUniqueId);
		
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Partical> loadAllQuarks() {
		
		String querySentence = "FROM Partical partical WHERE partical.particalType = :particalType";
		
		return genericDaoSupport.searchForList(querySentence, "particalType", ParticalType.QUARK);
	}

	@Override
	public boolean isQuarkPartical(String uniqueId) {
		
		if(StringUtils.isEmpty(uniqueId)){
			
			return false;
		}
		Filter filter = new Filter();
		
		filter.addEquals("particalType", ParticalType.QUARK);
		
		filter.addEquals("particalStatus", ParticalStatus.ONLINE);
		
		filter.addEquals("uniqueParticalId", uniqueId);
		
		return CollectionUtils.isNotEmpty(list(Partical.class, filter));
	}
	@Override
	public String getQuarkApIUrl(String uniqueId, String apiName) throws CommonException {
		
		String quarkPrefix = getQuarkHostUrl(uniqueId);
		
		String syncAppConfigAPIName;
		
		ParticalModel particalModel = particalModelService.getParticalModel(uniqueId,apiName);
		
		if(null == particalModel){
			
			throw new CommonException(ErrorCode4ParticalSystem.ERROR_PARTICALMODEL_NOT_FOUND);
		}
		syncAppConfigAPIName = particalModel.getValue();
		
		if( !quarkPrefix .endsWith("/") && !syncAppConfigAPIName.startsWith("/")){
			
			quarkPrefix += "/";
		}
		
		String syncAppConfigAPIUrl = quarkPrefix + syncAppConfigAPIName;
		
		return syncAppConfigAPIUrl;
	}
	private String getQuarkHostUrl(String uniqueId)throws CommonException {
		
		if(StringUtils.isEmpty(uniqueId)){
			//TODO commonException
			throw new CommonException(GlobalSpec4Earth.ERROR_ILLEGAL_PARAMS);
		}
		
		Partical partical = getParticalByUniqueId(uniqueId);
		
		if(null == partical){
			
			throw new CommonException(ErrorCode4ParticalSystem.ERROR_PARTICAL_NOT_FOUND);
		}
		return partical.getEntryUrl();
		
	}

	@Override
	public List<Partical> loadAllQuarksByAppId(String appId) {
		
		List<String> particalUniqueIds = appParticlesService.getQuarkParticalUniqueIds(appId);
		
		List<Partical> particals = new ArrayList<Partical>();
		
		for(String particalUniqueId : particalUniqueIds){
			
			particals.add(getParticalByUniqueId(particalUniqueId));
		}
		
		return particals;
	}
}
